package com.pjs.tdd;

import static com.pjs.tdd.DataProvider.pounds;
import static com.pjs.tdd.NegativeTransaction.negativeTransaction;
import static com.pjs.tdd.PositiveTransaction.positiveTransaction;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.mockito.Mock;

import com.pjs.tdd.AbstractTransaction.TransactionType;
import com.pjs.test.framework.AbstractUnitTestCase;

public class TransactionTest extends AbstractUnitTestCase<Transaction> {
	
	private @Mock Money moneyMock; 

	public TransactionTest() {
		super(Transaction.class);
	}
	
	@Test
	public void transactionHasRequiredType(){
		classUnderTest=negativeTransaction(pounds(1000));
		assertEquals("transaction type should be negative", classUnderTest.type(),TransactionType.negative);
	}
	
	@Test(expected=TransactionException.class)
	public void transactionHasValidAmount(){
		negativeTransaction(pounds(-1000.10));
	}
	
	@Test(expected=TransactionException.class)
	public void transactionHasValidAmountUsingMock(){
		//given
		when(moneyMock.amount()).thenReturn(-1000.100);
		//when
		negativeTransaction(moneyMock);
		
		//expect exception
	}
	
	@Test
	public void negativeTransactionShouldReduceAmount(){
		Money money=negativeTransaction(pounds(1000)).apply(pounds(1000));
		assertNotNull("Money is unconstructed",money);
		assertEquals(pounds(0),money);
	}
	
	@Test
	public void positiveTransactionShouldIncreaseAmount(){
		Money money=positiveTransaction(pounds(1000)).apply(pounds(1000));
		assertNotNull("Money is unconstructed",money);
		assertEquals(pounds(2000),money);
	}
}
